from AIsearch import Search, AIcontrol
from AIsearch.getInfor import Get_Map_Info
class Decision(Search.Player_way):
    # 创建类 ，传入 起始点 目标点 地图（与test保持一致） 人物（与test 保持一致）
    def __init__(self, CurrentMap, Player, start_list=[], target_list=[]):
        self.mapinformation = []
        self.start_list = start_list
        self.target_list = target_list
        self.CurrentMap = CurrentMap
        self.open_list = {}
        self.close_list = {}
        self.Player = Player
        self.final_list = []
        self.f_list = []
        self.state = 0
        self.blood = {}
        self.connect = []
        self.checklist = []
        self.low_floor = 0
    def refresh(self, start_list, target_list):
        self.start_list = start_list
        self.target_list = target_list
        self.open_list = {}
        self.close_list = {}
        self.final_list = []
        self.f_list = []
        if self.Player.floor<self.low_floor:
            self.low_floor = self.Player.floor
    def Astar(self):
        commands = []
        T_or_F = self.astar_search()  # 若成功返回血量，失败返回 -1
        if T_or_F is not -1:
            commands = self.Getway_out()  # 获得控制率
            print("After going this way, my blood is {} ".format(T_or_F))
        else:
            return [None, -1]
        return [commands, T_or_F]
    def totalBloodposition(self):
        self.position = []
        if AIcontrol.FindPoint_a(self.CurrentMap, self.Player.floor, 31)!=None:
            self.position.extend(AIcontrol.FindPoint_a(self.CurrentMap, self.Player.floor, 31))
        if AIcontrol.FindPoint_a(self.CurrentMap, self.Player.floor, 31) != None:
            self.position.extend(AIcontrol.FindPoint_a(self.CurrentMap, self.Player.floor, 32))

        self.merge()

            #if position != None:
            #    k = []
            #    k.extend([self.Player.floor])
            #    k.append(position)
            #    self.blood.append(k)
            #else:
            #    print("Sorry, not found!")

    def merge(self): #每到新地图只使用一次
        self.classify = {'connect': [], "disconnect": []}
        self.clist = self.createlist()
        if self.position==[]:
            return print("None blood!")
        while True:
            if len(self.position)==0:
                break
            pos = self.position[0]
            self.connect = []
            self.find(pos[0], pos[1])
            if len(self.connect)>1:
                self.classify['connect'].append(self.connect)
                for value in self.connect:
                    self.position.remove(value)
            elif len(self.connect)==1:
                self.classify['disconnect'].extend(self.connect)
                self.position.remove(self.connect[0])
            self.blood[str(self.Player.floor)] = self.classify

    def find(self,x,y):
        if self.clist[x][y]==1:
            return
        id = Get_Map_Info(self.CurrentMap, self.Player.floor, [x, y])
        if id == 2:
            return
        elif id == 31 or id == 32 or id == 0:
            if id==31 or id==32:
                self.connect.append([x, y])
            (self.clist)[x][y]=1
            if self.clist[x+1][y] == 0:
                self.find(x+1, y)
            if self.clist[x-1][y] == 0:
                self.find(x-1, y)
            if self.clist[x][y+1] == 0:
                self.find(x, y+1)
            if self.clist[x][y-1] == 0:
                self.find(x, y-1)
        return

    def createlist(self):
        clist = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
        return clist

    #确定本层血瓶位置
    #确定出口入口位置
    def decisionline(self):
        #地图读取信息部分，到新的层数才会执行
        if str(self.Player.floor) not in self.blood:
            self.blood[str(self.Player.floor)] = {'connect': [], "disconnect": []}
            self.totalBloodposition()
        #正常状态下知识库给出入口和出口
        if self.state == 0:
            Type = 0
            self.out = AIcontrol.FindPoint(self.CurrentMap, self.Player.floor, 88)
        #异常状态下搜索最优增益血瓶位置作为目标点
        elif self.state==1:
            [Type,self.out]=self.return_best_blood()
            #print("**************************************")
        return [Type, self.out]

    def search_cost(self, floor): #对指定层，一般floor设置为self.Player.floor
        disconnect_list = self.blood[str(floor)]['disconnect']#[[1,1],[2,2],[3,3]]
        #print('-------------------------------------------')
        #print(disconnect_list)
        #print('--------------------------------------------')
        #disconnect_list.append([-999,-999])
        connect_list = self.blood[str(floor)]['connect']#[[[1,1],[2,2],[2,3]], [[5,5],[7,7]]]
        #print('+++++++++++++++++++++++++++++++++++++++++++')
        #print(connect_list)
        #print('+++++++++++++++++++++++++++++++++++++++++++')
        #connect_list.append([-999,-999])
        dis_gain = []
        con_gain = []
        if disconnect_list is not None:
            for i in range(len(disconnect_list)):
                target_1 = disconnect_list[i]
                #target_1 = disconnect_list[i][0]
                item_type = Get_Map_Info(self.CurrentMap, floor, target_1)
                self.refresh(self.Player.pos, target_1)
                gain_1 = self.Player.hp
                gain_2 = self.Astar()[1]
                if gain_2 > 0:
                    gain = gain_2 - gain_1
                    if item_type == 31:
                        gain = gain + 100
                    elif item_type == 32:
                        gain = gain + 200
                    elif item_type == 33:
                        gain = gain + 400
                    elif item_type == 34:
                        gain = gain + 800
                elif gain_2 == -1: #返回错误信息
                    gain = -99999
                dis_gain.append([target_1, gain]) #返回列表[ [[1,2], 200], [[3,5], -9999] ]
        if connect_list is not None:
            for i in range(len(connect_list)):
                #初始化代价变量
                self.refresh(self.Player.pos, connect_list[i][0])
                gain_3 = self.Player.hp
                #print("start: {}".format(self.start_list))
                #print("end:{} ".format(self.target_list))
                gain_4 = self.Astar()[1]
                #print(gain_4)
                if gain_4 > 0:
                    gain_ = gain_4 - gain_3
                    #print(gain_)
                elif gain_4 == -1:
                    gain_ = -99999
                for j in range(len(connect_list[i])):
                    id_ = Get_Map_Info(self.CurrentMap, floor, connect_list[i][j])
                    if id_ == 31:
                        gain_ = gain_ + 100
                    elif id_ == 32:
                        gain_ = gain_ + 200
                    elif id_ == 33:
                        gain_ = gain_ + 400
                    elif id_ == 34:
                        gain_ = gain_ + 800
                con_gain.append([connect_list[i], gain_]) #返回列表[ [[[1,1],[2,2]],1000],  [[[2,3],[555,666]], -999999] ]
        cost_dict = {str(floor):{'connect':con_gain,'disconnect':dis_gain}}
        #print('aaaaaaaaaaaaaaaaaaaaaaa')
        #print(cost_dict)
        #print('bbbbbbbbbbbbbbbbbbbbbbb')
        return cost_dict #{'-1':{'connect':con_gain, 'disconnect':dis_gain}}

    def return_best_blood(self):  # 针对当前层
        con_gain = self.search_cost(self.Player.floor)[str(self.Player.floor)]['connect']
        dis_gain = self.search_cost(self.Player.floor)[str(self.Player.floor)]['disconnect']
        disconnect_list = self.blood[str(self.Player.floor)]['disconnect']
        connect_list = self.blood[str(self.Player.floor)]['connect']

        total = []
        gain_list_0 = []
        gain_list_1 = []

        for i in range(len(con_gain)):
            gain_list_0.append(con_gain[i][1])
            total.append(con_gain[i])
        for i in range(len(dis_gain)):
            gain_list_1.append(dis_gain[i][1])
            total.append(dis_gain[i])

        #判断是否非空
        #全部非空

        if len(gain_list_0) != 0 and len(gain_list_1) != 0:
            max_index_0 = gain_list_0.index(max(gain_list_0))
            #print("************************************************************************************")
            #print(gain_list_0)
            max_index_1 = gain_list_1.index(max(gain_list_1))
            #print("?????????????????????????????????????????????????????????????????????????????????????")
            #print(gain_list_1)
            if con_gain[max_index_0][1] > dis_gain[max_index_1][1]:
                temp = max_index_0
                Type_cao = 1  # 代表集群
            elif con_gain[max_index_0][1] <= dis_gain[max_index_1][1]:
                temp = max_index_1 + len(con_gain)
                Type_cao = 0  # 代表孤立

        #集群非空，孤立空
        elif len(gain_list_0) != 0 and len(gain_list_1) == 0:
            temp = gain_list_0.index(max(gain_list_0))
            Type_cao =  1
        #孤立非空，集群空
        elif len(gain_list_0) == 0 and len(gain_list_1) != 0:
            temp = gain_list_1.index(max(gain_list_0))
            Type_cao = 0


        # 删除更新
        #if total[temp][1] > 0:
        if Type_cao == 1:  # 集群
            connect_list.remove(total[temp][0])
            self.blood[str(self.Player.floor)]['connect'] = connect_list
        elif Type_cao == 0:  # 孤立
            disconnect_list.remove(total[temp][0])
            self.blood[str(self.Player.floor)]['disconnect'] = disconnect_list
        return [Type_cao, total[temp][0]]  # 返回位置和标志
        #else:
        #    return [-1, [0, 0]]  # 报错信息

    #返回当前层所有增益为正的位置，返回一个集群列表
    def greedy_eat(self):
        #读取剩余的代价列表
        con_gain = self.search_cost(self.Player.floor)[str(self.Player.floor)]['connect']
        dis_gain = self.search_cost(self.Player.floor)[str(self.Player.floor)]['disconnect']
        disconnect_list = self.blood[str(self.Player.floor)]['disconnect']
        connect_list = self.blood[str(self.Player.floor)]['connect']
        return_list = []
        #全非空
        if len(con_gain) != 0 and len(dis_gain) != 0:
            for i in range(dis_gain):
                if dis_gain[i][1] > 0:
                    return_list.append(dis_gain[i][0])
                    disconnect_list.remove(dis_gain[i])
            for i in range(con_gain):
                if con_gain[i][1] > 0:
                    for j in range(con_gain[i]):
                        return_list.append(con_gain[i][0][j])
                    connect_list.remove(con_gain[i])
        #集群非空，孤立空
        elif len(con_gain) != 0 and len(dis_gain) == 0:
            for i in range(con_gain):
                if con_gain[i][1] > 0:
                    for j in range(con_gain[i]):
                        return_list.append(con_gain[i][0][j])
                    connect_list.remove(con_gain[i])
        #孤立非空，集群空
        elif len(con_gain) == 0 and len(dis_gain) != 0:
            for i in range(dis_gain):
                if dis_gain[i][1] > 0:
                    return_list.append(dis_gain[i][0])
                    disconnect_list.remove(dis_gain[i])
        #观测更新
        self.blood[str(self.Player.floor)]['connect'] = connect_list
        self.blood[str(self.Player.floor)]['disconnect'] = disconnect_list
        return return_list
        #tips:返回的return_list = [[1,1],[2,2],[3,3],[4,4]]为所有坐标的集群列表
